# pybearcat.py - Uniden scanner library - Copyright 2011 by Steve McGrath
# Some code and inspiration taken from code by Vladimir N. Vorobev

import serial
import logging

import constants

class Scanner:
    
    port = None
    log = None
    
    def __init__(self, port, speed=115200):
        """Create a new Scanner object
        port: string specifying the serial port to use
        speed: desired baud rate, defaults to 115200
        """
        
        self.log = logging.getLogger(__name__)
        self.log.info("__init__ opening port %s at %d baud", port, speed)
        try:
            self.port = serial.Serial(port, speed, timeout=1)
            self.log.info("Connection opened")
        except serial.SerialException:
            self.log.warn("Error opening serial port")
    
    
    def _send_data(self, data):
        """Convenience function to send data to the serial port
        data: ASCII string to send
        """
        if self.port:
            try:
                self.log.debug("send_data: %s" % data)
                return self.port.write(data)
            except serial.SerialException:
                self.log.error("SerialException occured in send_data")
                pass
    
    
    def _receive_response(self):
        """Read a response from the scanner.
        returns the response received as a string
        """
        response = None
        if self.port:
            while not response:
                response = self._readline()
        self.log.debug("receive_response: %s" % response)
        return answer
    
    
    def command(self, cmd, params = ''):
        """Send a command, optionally with parameters.
        cmd: the command to send
        params: the parameters to the command
        
        returns the response received from the scanner or None on error
        """
        if self.port:
            # TODO: clean up this line, it's hard to parse.
            if self._send_data((','.join([cmd, params]) if params else cmd) + '\r'):
                return self._receive_response()
        else:
            return None


    def _readline(self, size=None, eol='\r'):
        """old-style pyserial readline implementation with configurable
        end-of-line character."""
        leneol = len(eol)
        line = bytearray()
        while True:
            c = self.port.read(1)
            if c:
                line += c
                if line[-leneol:] == eol:
                    break
                if size is not None and len(line) >= size:
                    break
            else:
                break
        return bytes(line)
    
    
    def __del__(self):
        """Cleanup, close serial port before object is destroyed
        """
        if self.port:
            self.port.close()